﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Npgsql;
using System.Data;
using DTO.Clases;
using System.Collections;

namespace DataAccessLayer.Clases
{
    /// <summary>
    /// Representa una clase de transacciones a Base de Datos de Dian.
    /// </summary>
    public class DaoDian
    {
        /// <summary>
        /// Representa una sentencia adapter en posgres sql.
        /// </summary>
        private NpgsqlDataAdapter miAdapter;

        /// <summary>
        /// Representa una sentenca en sql.
        /// </summary>
        private NpgsqlCommand miComando;

        /// <summary>
        /// Representa el objeto de conexión.
        /// </summary>
        private Conexion miConexion;

        /// <summary>
        /// Representa una tabla de datos en memoria.
        /// </summary>
        //  private DataTable miDateTable; 

        /// <summary>
        /// Representa la función insertar_dian.
        /// </summary>
        private string sqlInsertarDian = "insertar_dian";

        /// <summary>
        /// Representa la función insertar_dian_credito.
        /// </summary>
        private string IngresaDianCredito = "insertar_dian_credito";

        /// <summary>
        /// representa la función consulta_dian.
        /// </summary>
        private string sqlConsultaDian = "consulta_dian";

        /// <summary>
        /// Representa la función: print_dian.
        /// </summary>
        private string Print_ = "print_dian";

        /// <summary>
        /// Representa la función: print_dian_credito.
        /// </summary>
        private string PrintCredito = "print_dian_credito";

        public DaoDian()
        {
            this.miConexion = new Conexion();
        }

        /// <summary>
        /// Ingresa los datos del Registro de la Dian en base de datos.
        /// </summary>
        /// <param name="dian">Registro de la Dian a Ingresar.</param>
        /// <param name="contado">Establece el valor que indica si el registro es para Facturas de contado.</param>
        public void InsertaDian(Dian dian, bool contado)
        {
            var miDaoFactura = new DaoFacturaVenta();
            try
            {
                if (contado)
                {
                    CargarComandoStoreProsedure(sqlInsertarDian);
                }
                else
                {
                    CargarComandoStoreProsedure(IngresaDianCredito);
                }
                miComando.Parameters.AddWithValue("numerodian", dian.NumeroResolucion);
                miComando.Parameters.AddWithValue("fecha", dian.FechaExpedicion);
                miComando.Parameters.AddWithValue("rangoinicio", dian.RangoInicial);
                miComando.Parameters.AddWithValue("rangofinal", dian.RangoFinal);
                miComando.Parameters.AddWithValue("serieinicial", dian.SerieInicial);
                miComando.Parameters.AddWithValue("seriefinal", dian.SerieFinal);
                miConexion.MiConexion.Open();
                miComando.ExecuteNonQuery();
                miConexion.MiConexion.Close();
                miComando.Dispose();
                miDaoFactura.ActualizarConsecutivo(dian.SerieInicial + dian.RangoInicial.ToString(), contado);
            }
            catch (Exception ex)
            {
                throw new Exception("Ocurrió un error al insertar el registro Dian.\n" + ex.Message);
            }
            finally { miConexion.MiConexion.Close(); }
        }

        /// <summary>
        /// Ago la consulta en la base dedatos 
        /// </summary>
        /// <returns></returns>
        public DataTable ConsultaDian()
        {
            var miTable = Tabla();
            try
            {
                var t = new DataTable();
                CargarAdapterStoredProcedure(sqlConsultaDian);
                miAdapter.Fill(t);
                foreach (DataRow row in t.Rows)
                {
                    var row_ = miTable.NewRow();
                    row_["id"] = row["iddian"];
                    row_["Resolucion"] = row["numeroresoluciondian"];
                    row_["Fecha"] = row["fechadian"];
                    row_["Desde"] = row["inicialestatica"] + row["rangoinicialdian"].ToString();
                    row_["Hasta"] = row["finalestatica"] + row["rangofinaldian"].ToString();
                    miTable.Rows.Add(row_);
                }

                return miTable;
            }
            catch (Exception ex)
            {
                throw new Exception("Error al consultar Dian." + ex.Message);
            }
        }

        /// <summary>
        /// Tabal general
        /// </summary>
        /// <returns></returns>
        private DataTable Tabla()
        {
            var miTabla = new DataTable();
            miTabla.Columns.Add(new DataColumn("id", typeof(int)));
            miTabla.Columns.Add(new DataColumn("Resolucion", typeof(string)));
            miTabla.Columns.Add(new DataColumn("Fecha", typeof(DateTime)));
            miTabla.Columns.Add(new DataColumn("Desde", typeof(string)));
            miTabla.Columns.Add(new DataColumn("Hasta", typeof(string)));
            return miTabla;
        }

        /// <summary>
        /// Obtiene los datos del registro de la DIAN para su impresión.
        /// </summary>
        /// <param name="contado">Indica si la factura emitida es de contado o no(crédito).</param>
        /// <returns></returns>
        public DataSet Print(bool contado)
        {
            var dataSet = new DataSet();
            try
            {
                if (contado)
                {
                    CargarAdapterStoredProcedure(Print_);
                }
                else
                {
                    CargarAdapterStoredProcedure(Print_);
                    miAdapter.SelectCommand.Parameters.AddWithValue("pago", contado);
                }
                miAdapter.Fill(dataSet, "TDian");
                return dataSet;
            }
            catch (Exception ex)
            {
                throw new Exception("Ocurrió un error al cargar los datos de la DIAN.\n" + ex.Message);
            }
        }

        /// <summary>
        /// Inicializa una nueva instancia de NpgsqlCommand de tipo StoredProcedure.
        /// </summary>
        /// <param name="cmd">Comando a ejecutar.</param>
        private void CargarComandoStoreProsedure(string cmd)
        {
            miComando = new NpgsqlCommand();
            miComando.Connection = miConexion.MiConexion;
            miComando.CommandType = CommandType.StoredProcedure;
            miComando.CommandText = cmd;
        }

        /// <summary>
        /// Inicializa una nueva instancia de NpgsqlDataAdapter de tipo Stored Procedure.
        /// </summary>
        /// <param name="cmd">Sentencia a ejecutar.</param>
        private void CargarAdapterStoredProcedure(string cmd)
        {
            miAdapter = new NpgsqlDataAdapter(cmd, miConexion.MiConexion);
            miAdapter.SelectCommand.CommandType = System.Data.CommandType.StoredProcedure;
        }
    }
}